{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e2996fea",
   "metadata": {},
   "source": [
    "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/langchain-ai/langchain-academy/blob/main/module-2/multiple-schemas.ipynb) [![Open in LangChain Academy](https://cdn.prod.website-files.com/65b8cd72835ceeacd4449a53/66e9eba12c7b7688aa3dbb5e_LCA-badge-green.svg)](https://academy.langchain.com/courses/take/intro-to-langgraph/lessons/58239434-lesson-3-multiple-schemas)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "693d9912-8d56-46a2-a445-3ee5651fe433",
   "metadata": {},
   "source": [
    "# Multiple Schemas\n",
    "\n",
    "## Review\n",
    "\n",
    "We just covered state schema and reducers.\n",
    "\n",
    "Typically, all graph nodes communicate with a single schema. \n",
    "\n",
    "Also, this single schema contains the graph's input and output keys / channels.\n",
    "\n",
    "## Goals\n",
    "\n",
    "But, there are cases where we may want a bit more control over this:\n",
    "\n",
    "* Internal nodes may pass information that is *not required* in the graph's input / output.\n",
    "\n",
    "* We may also want to use different input / output schemas for the graph. The output might, for example, only contain a single relevant output key.\n",
    "\n",
    "We'll discuss a few ways to customize graphs with multiple schemas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "4d727cc2-5a43-4eb5-9d69-82bbbcc35bd9",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%capture --no-stderr\n",
    "%pip install --quiet -U langgraph"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "29b3d109-6bf2-4271-9775-556ee4bd900d",
   "metadata": {},
   "source": [
    "## Private State\n",
    "\n",
    "First, let's cover the case of passing [private state](https://langchain-ai.github.io/langgraph/how-tos/pass_private_state/) between nodes.\n",
    "\n",
    "This is useful for anything needed as part of the intermediate working logic of the graph, but not relevant for the overall graph input or output.\n",
    "\n",
    "We'll define an `OverallState` and a `PrivateState`.\n",
    "\n",
    "`node_2` uses `PrivateState` as input, but writes out to `OverallState`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "038ca2e4-7d6d-49d5-b213-b38469cde434",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from typing_extensions import TypedDict\n",
    "from IPython.display import Image, display\n",
    "from langgraph.graph import StateGraph, START, END\n",
    "\n",
    "class OverallState(TypedDict):\n",
    "    foo: int\n",
    "\n",
    "class PrivateState(TypedDict):\n",
    "    baz: int\n",
    "\n",
    "def node_1(state: OverallState) -> PrivateState:\n",
    "    print(\"---Node 1---\")\n",
    "    return {\"baz\": state['foo'] + 1}\n",
    "\n",
    "def node_2(state: PrivateState) -> OverallState:\n",
    "    print(\"---Node 2---\")\n",
    "    return {\"foo\": state['baz'] + 1}\n",
    "\n",
    "# Build graph\n",
    "builder = StateGraph(OverallState)\n",
    "builder.add_node(\"node_1\", node_1)\n",
    "builder.add_node(\"node_2\", node_2)\n",
    "\n",
    "# Logic\n",
    "builder.add_edge(START, \"node_1\")\n",
    "builder.add_edge(\"node_1\", \"node_2\")\n",
    "builder.add_edge(\"node_2\", END)\n",
    "\n",
    "# Add\n",
    "graph = builder.compile()\n",
    "\n",
    "# View\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3dc9cd64-4bd3-4c0a-8f8f-d58c551428e3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---Node 1---\n",
      "---Node 2---\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'foo': 3}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph.invoke({\"foo\" : 1})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50a29f37-f653-4a56-ad0a-345d7f632ea0",
   "metadata": {},
   "source": [
    "`baz` is only included in `PrivateState`.\n",
    "\n",
    "`node_2` uses `PrivateState` as input, but writes out to `OverallState`.\n",
    "\n",
    "So, we can see that `baz` is excluded from the graph output because it is not in `OverallState`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75a8362f-009b-4ec2-abe5-8fb318e39966",
   "metadata": {},
   "source": [
    "## Input / Output Schema\n",
    "\n",
    "By default, `StateGraph` takes in a single schema and all nodes are expected to communicate with that schema. \n",
    "\n",
    "However, it is also possible to [define explicit input and output schemas for a graph](https://langchain-ai.github.io/langgraph/how-tos/input_output_schema/?h=input+outp).\n",
    "\n",
    "Often, in these cases, we define an \"internal\" schema that contains *all* keys relevant to graph operations.\n",
    "\n",
    "But, we use specific `input` and `output` schemas to constrain the input and output.\n",
    "\n",
    "First, let's just run the graph with a single schema."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5323068a-907a-438c-8db5-46e5d452ad72",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "class OverallState(TypedDict):\n",
    "    question: str\n",
    "    answer: str\n",
    "    notes: str\n",
    "\n",
    "def thinking_node(state: OverallState):\n",
    "    return {\"answer\": \"bye\", \"notes\": \"... his is name is Lance\"}\n",
    "\n",
    "def answer_node(state: OverallState):\n",
    "    return {\"answer\": \"bye Lance\"}\n",
    "\n",
    "graph = StateGraph(OverallState)\n",
    "graph.add_node(\"answer_node\", answer_node)\n",
    "graph.add_node(\"thinking_node\", thinking_node)\n",
    "graph.add_edge(START, \"thinking_node\")\n",
    "graph.add_edge(\"thinking_node\", \"answer_node\")\n",
    "graph.add_edge(\"answer_node\", END)\n",
    "\n",
    "graph = graph.compile()\n",
    "\n",
    "# View\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "853fc90c-bf82-4d51-b3a5-ceb0b0ae5233",
   "metadata": {},
   "source": [
    "Notice that the output of invoke contains all keys in `OverallState`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "507d35e6-f65c-4e89-b26e-a0ef7b90be83",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'question': 'hi', 'answer': 'bye Lance', 'notes': '... his is name is Lance'}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph.invoke({\"question\":\"hi\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5a899c3-e1b0-48eb-9a36-8c787e378ef0",
   "metadata": {},
   "source": [
    "Now, let's use a specific `input` and `output` schema with our graph.\n",
    "\n",
    "Here, `input` / `output` schemas perform *filtering* on what keys are permitted on the input and output of the graph. \n",
    "\n",
    "In addition, we can use a type hint `state: InputState` to specify the input schema of each of our nodes.\n",
    "\n",
    "This is important when the graph is using multiple schemas.\n",
    "\n",
    "We use type hints below to, for example, show that the output of `answer_node` will be filtered to `OutputState`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "682b3d10-c78a-41c2-a5ff-842e1688c95f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "{'answer': 'bye Lance'}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class InputState(TypedDict):\n",
    "    question: str\n",
    "\n",
    "class OutputState(TypedDict):\n",
    "    answer: str\n",
    "\n",
    "class OverallState(TypedDict):\n",
    "    question: str\n",
    "    answer: str\n",
    "    notes: str\n",
    "\n",
    "def thinking_node(state: InputState):\n",
    "    return {\"answer\": \"bye\", \"notes\": \"... his is name is Lance\"}\n",
    "\n",
    "def answer_node(state: OverallState) -> OutputState:\n",
    "    return {\"answer\": \"bye Lance\"}\n",
    "\n",
    "graph = StateGraph(OverallState, input=InputState, output=OutputState)\n",
    "graph.add_node(\"answer_node\", answer_node)\n",
    "graph.add_node(\"thinking_node\", thinking_node)\n",
    "graph.add_edge(START, \"thinking_node\")\n",
    "graph.add_edge(\"thinking_node\", \"answer_node\")\n",
    "graph.add_edge(\"answer_node\", END)\n",
    "\n",
    "graph = graph.compile()\n",
    "\n",
    "# View\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))\n",
    "\n",
    "graph.invoke({\"question\":\"hi\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1e5ff21",
   "metadata": {},
   "source": [
    "We can see the `output` schema constrains the output to only the `answer` key."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
